//
//  Modules.swift
//  JKTool
//
//  Created by 姜奎 on 2023/4/12.
//

import Foundation
import PathKit
import XcodeProj

extension JKTool {
    struct Modules: ParsableCommand {
        static var configuration = CommandConfiguration(
            commandName: "module",
            _superCommandName: "jktool",
            abstract: "项目更新子库对于固定工程格式封装",
            version: "1.0.0",subcommands: [Update.self,Init.self, Generate.self])
    }
}

extension JKTool.Modules {
    struct Update: ParsableCommand {
        static var configuration = CommandConfiguration(
            commandName: "update",
            _superCommandName: "module",
            abstract: "利用git clone构建/更新项目结构",
            version: "1.0.0")
        
        @Option(name: .shortAndLong, help: "利用git submodule构建/更新项目结构，default：false")
        var submodule: Bool?
        
        @Option(name: .shortAndLong, help: "是否自动利用git submodule构建/更新项目结构，仅在`submodule = true`时有效，default：false")
        var autoAddSubmodule: Bool?
        
        @Option(name: .long, help: "移除不在submodules中的submodule，default：false")
        var prune: Bool?
        
        @Option(name: .shortAndLong, help: "更新submodules为远程项目的最新版本，default：false")
        var remote: Bool?
        
        @Option(name: .shortAndLong, help: "分支名")
        var branch: String?

        @Option(name: .shortAndLong, help: "兜底分支")
        var currentBranch: String?

        @Option(name: .shortAndLong, help: "强制 checkout，default：false")
        var force: Bool = false
        
        @Option(name: .shortAndLong, help: "遇到错误时终止，default：false")
        var exitError: Bool = false
        
        @Option(name: .shortAndLong, help: "执行目录")
        var path: String?
        
        mutating func run() {
            
            guard let project = Project.project(directoryPath: path ?? FileManager.default.currentDirectoryPath) else {
                return po(tip: "\(path ?? FileManager.default.currentDirectoryPath)目录没有检索到工程", type: .error)
            }
            
            guard project.rootProject == project else {
               return po(tip: "请在项目根目录执行脚本", type: .error)
            }
            
            var args = [String]()
            
            if let prune = prune {
                args.append(contentsOf: ["--prune",String(prune)])
            }
            
            if let remote = remote {
                args.append(contentsOf: ["--remote",String(remote)])
            }
            
            if let branch = branch {
                args.append(contentsOf: ["--branch",String(branch)])
            }

            if let currentBranch = currentBranch {
                args.append(contentsOf: ["--current-branch",String(currentBranch)])
            }

            args.append(contentsOf: ["--force",String(force)])
            
            args.append(contentsOf: ["--exit-error",String(exitError)])
            
            args.append(contentsOf: ["--path",String(project.directoryPath)])
            
//            let gitSubmodules = project.gitSubmodules
            
//            if  !gitSubmodules.isEmpty || submodule == true {
            if submodule == true {
                if let autoAddSubmodule = autoAddSubmodule {
                    args.append(contentsOf: ["--auto-add-submodule",String(autoAddSubmodule)])
                }
                JKTool.Git.SubModule.main(args)
            } else {
                JKTool.Git.Clone.main(args)
            }
        }
    }
}


extension JKTool.Modules {
    
    struct Init: ParsableCommand {
        static var configuration = CommandConfiguration(
            commandName: "init",
            _superCommandName: "module",
            abstract: "clone项目，并利用git clone构建/更新项目结构",
            version: "1.0.0")

        
        @Option(name: .shortAndLong, help: "项目git地址")
        var url: String
        
        @Option(name: .long, help: "保存目录【绝对路径】")
        var path: String?
        
        @Option(name: .shortAndLong, help: "利用git submodule构建/更新项目结构，default：false")
        var submodule: Bool?
        
        @Option(name: .shortAndLong, help: "是否自动利用git submodule构建/更新项目结构，仅在`submodule = true`时有效，default：false")
        var autoAddSubmodule: Bool?
        
        @Option(name: .shortAndLong, help: "移除不在submodules中的module，default：false")
        var prune: Bool?
        
        @Option(name: .shortAndLong, help: "更新submodules为远程项目的最新版本，default：false")
        var remote: Bool?
        
        @Option(name: .shortAndLong, help: "强制 checkout，default：false")
        var force: Bool = false
        
        @Option(name: .shortAndLong, help: "遇到错误时终止，default：false")
        var exitError: Bool = false
        
        @Option(name: .shortAndLong, help: "分支名")
        var branch: String?

        @Option(name: .shortAndLong, help: "兜底分支")
        var currentBranch: String?

        mutating func run() {
            
            let path = path ?? FileManager.default.currentDirectoryPath
            let fileList = FileManager.default.getFileList(directoryPath: path)
            let isEmpty = fileList?.isEmpty ?? true
            
            if isEmpty == true {
                po(tip: "======开始准备clone项目======")
                let date = Date.init().timeIntervalSince1970
                
                do {
                    po(tip: "【\(path.destination())】开始执行：git clone")
                    try shellOut(to: .gitClone(url: url, to: path))
                    po(tip:"【\(path.destination())】clone成功[\(GlobalConstants.duration(to: date) + " s")]")
                } catch {
                    let error = error as! ShellOutError
                    po(tip:  error.message + error.output,type: .error)
                }
            }
            
            JKTool.Git.Reset.main(["--path",path, "--exit-error",String(exitError)])
            JKTool.Git.Checkout.main(["--path",path, "--branch",branch ?? "master", "--current-branch", currentBranch ?? "master", "--force", String(force), "--exit-error",String(exitError)])

            var args = [String]()
            
            if let submodule = submodule {
                args.append(contentsOf: ["--submodule",String(submodule)])
            }
            
            if let autoAddSubmodule = autoAddSubmodule {
                args.append(contentsOf: ["--auto-add-submodule",String(autoAddSubmodule)])
            }
            
            if let prune = prune {
                args.append(contentsOf: ["--prune",String(prune)])
            }
            
            if let remote = remote {
                args.append(contentsOf: ["--remote",String(remote)])
            }
            
            if let branch = branch {
                args.append(contentsOf: ["--branch",String(branch)])
            }
            
            if let currentBranch = currentBranch {
                args.append(contentsOf: ["--current-branch",String(currentBranch)])
            }

            args.append(contentsOf: ["--force",String(force)])
            
            args.append(contentsOf: ["--exit-error",String(exitError)])
            
            args.append(contentsOf: ["--path",String(path)])
            
            JKTool.Modules.Update.main(args)
        }
    }
}

extension JKTool.Modules {

    struct Generate: ParsableCommand {
        static var configuration = CommandConfiguration(
            commandName: "generate-xcodeproj",
            _superCommandName: "module",
            abstract: "构建*-Debugging子模块管理树",
            version: "1.0.0")


        @Option(name: .shortAndLong, help: "项目目录")
        var path: String?

        mutating func run() {

            guard let project = Project.project(directoryPath: path ?? FileManager.default.currentDirectoryPath) else {
                return po(tip: "\(path ?? FileManager.default.currentDirectoryPath)目录不存在", type: .error)
            }
            let builder = XcodeProjBuilder( path: Path(project.checkoutsPath).parent(),name: project.directoryEntrance)

            do {
                po(tip: "【\(project.directoryEntrance)】准备构建子模块管理树！")
                try builder.generateXcodeproj(with: project)
                po(tip: "【\(project.directoryEntrance)】子模块管理树构建完成。")
            } catch {
                po(tip: "【\(project.directoryEntrance)】子模块管理树构建失败。\n\(error.localizedDescription)")
            }
        }
    }
}
